
from typing import List

from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session

import crud
import models
import schemas

from database import SessionLocal, engine
from utils import *
from face_recongnition import calc_face_feature

models.Base.metadata.create_all(bind=engine)
# Create the database tables

app = FastAPI()


# Dependency
def get_db():
    try:
        db = SessionLocal()
        yield db
    finally:
        db.close()


@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
    # 这里的db 实际是 SessionLocal 实例， 但是也是 Session， 这里直接type hint Session 方便代码补全
    db_user = crud.get_user_by_name(db, name=user.name)
    if db_user:
        raise HTTPException(status_code=400, detail="Name already registered")
    img_idx = user.imgidx
    img_path = os.path.join("dataset", user.name)
    if not os.path.exists(img_path):
        os.makedirs(img_path)
    base64_code = user.imgbase64
    img = base64_cv2(base64_code)
    if img_idx < 5:
        
        cv2_imwrite(os.path.join(img_path, "{}_{}.jpg".format(user.name, img_idx)), img)
        raise HTTPException(status_code=400, detail="not enough images")
    else:
        is_success, feature_average = calc_face_feature(img_path)
        print(img_path, is_success, type(feature_average))
        if is_success:
            user.facevalue = feature_average
        
        return crud.create_user(db=db, user=user)


@app.post("/users/imgs/", response_model=bool)
def collect_user_img(user: schemas.UserBase):
    #
    data = request.get_data().decode('utf-8')
    #json.loads将string转换为dict
    data = json.loads(data)
    #获取dict中'img'标签的数据
    image_b64 = data["img"]
    #进行base64解码工作 base64->数组
    image_decode = base64.b64decode(image_b64)
    #fromstring实现了字符串到Ascii码的转换
    nparr = np.fromstring(image_decode, np.uint8)
    #从nparr中读取数据，并把数据转换(解码)成图像格式
    img_np = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
    cv2_imwrite('test.jpg',img_np)
    return  True


@app.get("/users/", response_model=List[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    users = crud.get_users(db, skip=skip, limit=limit)
    return users


# @app.get("/users/{user_id}", response_model=schemas.User)
# def read_user(user_id: int, db: Session = Depends(get_db)):
#     db_user = crud.get_user(db, user_id=user_id)
#     if db_user is None:
#         raise HTTPException(status_code=404, detail="User not found")
#     return db_user


@app.get("/users/{user_name}", response_model=schemas.User)
def get_user_by_name(user_name: str, db: Session = Depends(get_db)):
    db_user = crud.get_user_by_name(db, name=user_name)
    if db_user is None:
        raise HTTPException(status_code=404, detail="User not found")
    return db_user


# 处理进入人员信息
@app.post("/enterusers/", response_model=schemas.EnterUser)
def create_enter_user(user: schemas.EnterUserCreate, db: Session = Depends(get_db)):
    # 这里的db 实际是 SessionLocal 实例， 但是也是 Session， 这里直接type hint Session 方便代码补全
    db_user = crud.get_enter_user_by_name(db, name=user.name)
    if db_user:
        raise HTTPException(status_code=400, detail="Name already registered")
    return crud.create_enter_user(db=db, user=user)


@app.post("/enterusers/edit/", response_model=bool)
def edit_enter_user(user: schemas.EnterUser, db: Session = Depends(get_db)):
    # 这里的db 实际是 SessionLocal 实例， 但是也是 Session， 这里直接type hint Session 方便代码补全
    return crud.edit_enter_user_by_name(db, user=user)

@app.get("/enterusers/", response_model=List[schemas.EnterUser])
def read_enter_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    users = crud.get_enter_users(db, skip=skip, limit=limit)
    return users

@app.get("/enterusers/{user_name}", response_model=schemas.EnterUser)
def get_enter_user_by_name(user_name: str, db: Session = Depends(get_db)):
    db_enter_user = crud.get_enter_user_by_name(db, name=user_name)
    if db_enter_user is None:
        raise HTTPException(status_code=404, detail="Enter User not found")
    return db_enter_user


@app.post("/enterusers/del/{del_name}", response_model=bool)
def del_enter_user_by_name(user_name: str, db: Session = Depends(get_db)):
    del_flag = crud.del_enter_user_by_name(db, name=user_name)
    if not del_flag :
        raise HTTPException(status_code=404, detail="Enter User not found")
    return del_flag



if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app='main:app', host="127.0.0.1", port=8090, reload=True, debug=True)

